ποΈGitΠ―ΡΠ°ποΈ
feature/docs/README.md bd2863243bab6eb213401d949839a2bc74dde7e2 (bd286324) Text, 6.49 KB
Tc9d1d9# `:feature:docs`
Tc9d1d9## Overview
The Ta5d6ff`:feature:docs` module is an **in-app documentation browser** with Compose Multiplatform UI. It bundles the Meshtastic user guide and developer guide as Compose resources at build time, provides full-text keyword search, Crowdin-backed multilingual content, optional ML Kit runtime translation (Google Play flavor), and a "Chirpy" AI Q&A assistant (Gemini Nano on Google Play; keyword fallback on F-Droid / Desktop / iOS).
**Targets:** Android Β· JVM (Desktop) Β· iOS (via Ta5d6ff`meshtastic.kmp.feature` convention plugin)
Tc9d1d9## Key Responsibilities
Tff7b72- Bundle Ta5d6ff`docs/en/user/**/*.md` and Ta5d6ff`docs/en/developer/**/*.md` as Compose resources at build time
Tff7b72- Sync Crowdin-translated locales into Ta5d6ff`composeResources/files/{locale}/docs/`
Tff7b72- Keyword search (TF-IDF style) across the full doc bundle
Tff7b72- Locale-aware content loading with Crowdin β ML Kit fallback chain
Tff7b72- Adaptive list/detail layout (single pane on phones, split pane on tablets/desktop)
Tff7b72- Chirpy AI assistant: streaming Q&A against in-app docs via Gemini Nano or keyword fallback
Tc9d1d9## Source Structure
Ta5d6ff```
src/commonMain/kotlin/org/meshtastic/feature/docs/
βββ ai/
β βββ AIDocAssistant.kt β interface (Gemini Nano / keyword fallback)
β βββ ChirpySessionHolder.kt
β βββ KeywordFallbackAssistant.kt
βββ data/
β βββ DocBundleLoader.kt β interface + DefaultDocBundleLoader
β βββ KeywordSearchEngine.kt β TF-IDF keyword search
βββ di/
β βββ FeatureDocsModule.kt β Koin module
βββ model/
β βββ DocModels.kt β DocSection, DocPage, DocBundle, DocSearchResult, ...
βββ navigation/
β βββ DocsNavigation.kt β docsEntries(), ChirpyUiState, rememberChirpyState()
βββ translation/
β βββ DocTranslationService.kt β ML Kit (Google) or no-op (fdroid/desktop/iOS)
β βββ DocTranslationCache.kt
β βββ MarkdownTranslationSegmenter.kt
β βββ NoOpDocTranslator.kt
βββ ui/
βββ DocsBrowserScreen.kt β list pane
βββ DocsPageRouteScreen.kt β detail pane
βββ DocsSearchBar.kt
βββ ChirpyAssistantSheet.kt β AI assistant bottom sheet
βββ ChirpyFab.kt β floating action button that opens Chirpy
βββ ComposeResourceImageTransformer.kt
βββ DocPageIconResolver.kt
βββ DocsPreviews.kt
```
Tc9d1d9## Key Types
Tc9d1d9### `DocSection` (sealed interface)
Ta5d6ff```Ta5d6ffkotlin
Tff7b72sealed Tff7b72interface T56d364DocSection Tb4b4b4{
Tff7b72data Tff7b72object T56d364UserGuide Tb4b4b4: Te6edf3DocSection
Tff7b72data Tff7b72object T56d364DeveloperGuide Tb4b4b4: Te6edf3DocSection
Tb4b4b4}
Ta5d6ff```
Tc9d1d9### `DocPage`
Ta5d6ff```Ta5d6ffkotlin
Tff7b72data Tff7b72class T56d364DocPageTb4b4b4(
Tff7b72val Te6edf3idTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3titleTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3sectionTb4b4b4: Te6edf3DocSectionTb4b4b4,
Tff7b72val Te6edf3navOrderTb4b4b4: Tffa657IntTb4b4b4,
Tff7b72val Te6edf3resourcePathTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3keywordsTb4b4b4: Te6edf3ListTff7b72<Tffa657StringTff7b72>Tb4b4b4,
Tff7b72val Te6edf3charCountTb4b4b4: Tffa657IntTb4b4b4,
Tb4b4b4)
Ta5d6ff```
Tc9d1d9### `AIDocAssistant` (interface)
Ta5d6ff```Ta5d6ffkotlin
Tff7b72interface T56d364AIDocAssistant Tb4b4b4{
Tff7b72suspend Tff7b72fun Td2a8ffisSupportedTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657Boolean
Tff7b72val Te6edf3modelStatusTb4b4b4: Te6edf3StateFlowTff7b72<Te6edf3ModelReadinessTff7b72>
Tff7b72suspend Tff7b72fun Td2a8ffanswerTb4b4b4(Te6edf3questionTb4b4b4: Tffa657StringTb4b4b4, Te6edf3currentPageIdTb4b4b4: Tffa657String? Tff7b72= Tff7b72nullTb4b4b4)Tb4b4b4: Te6edf3AIDocAssistantResult
Tff7b72fun Td2a8ffanswerStreamTb4b4b4(Te6edf3questionTb4b4b4: Tffa657StringTb4b4b4, Te6edf3currentPageIdTb4b4b4: Tffa657String? Tff7b72= Tff7b72nullTb4b4b4)Tb4b4b4: Te6edf3FlowTff7b72<Te6edf3AIDocAssistantResultTff7b72>
Tff7b72fun Td2a8ffresetSessionTb4b4b4(Tb4b4b4)
Tb4b4b4}
Ta5d6ff```
Ta5d6ff`AIDocAssistantResult` is a sealed interface: Ta5d6ff`Partial`, Ta5d6ff`Success`, Ta5d6ff`Fallback`, Ta5d6ff`Error`.
Platform bindings:
Tff7b72- **Google flavor**: Gemini Nano via on-device ML
Tff7b72- **F-Droid / Desktop / iOS**: Ta5d6ff`KeywordFallbackAssistant` (keyword search + summarisation, no network)
Tc9d1d9### `ChirpyMessage`
Ta5d6ff```Ta5d6ffkotlin
Tf0883e@Serializable
Tff7b72data Tff7b72class T56d364ChirpyMessageTb4b4b4(
Tff7b72val Te6edf3idTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3roleTb4b4b4: Te6edf3ChirpyRoleTb4b4b4, T8b949e// USER | ASSISTANT | SYSTEM
Tff7b72val Te6edf3textTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3sourcesTb4b4b4: Te6edf3ListTff7b72<Te6edf3SourceRefTff7b72>Tb4b4b4,
Tb4b4b4)
Ta5d6ff```
Tc9d1d9## Gradle Tasks
Two custom tasks keep bundled docs in sync:
| Task | Description |
|---|---|
| Ta5d6ff`syncDocsToComposeResources` | Copies Ta5d6ff`docs/en/user/**/*.md` and Ta5d6ff`docs/en/developer/**/*.md` into Ta5d6ff`src/commonMain/composeResources/files/docs/`, plus Ta5d6ff`docs/assets/screenshots/**/*.png` into Ta5d6ff`.../files/docs/assets/screenshots/`. Runs automatically before resource generation. |
| Ta5d6ff`syncTranslatedDocsToComposeResources` | Copies Crowdin-translated locales from Ta5d6ff`docs/{locale}/user/**/*.md` into Ta5d6ff`src/commonMain/composeResources/files/{locale}/docs/` using CMP qualifier format (e.g. Ta5d6ff`pt-rBR`). |
These tasks run automatically β no manual invocation is required during normal development.
Tc9d1d9## Navigation
Routes (registered under the Settings nav graph):
| Route | Description |
|---|---|
| Ta5d6ff`SettingsRoute.HelpDocs` | Doc browser list pane |
| Ta5d6ff`SettingsRoute.HelpDocPage` | Individual doc page detail pane |
The Ta5d6ff`docsEntries()` extension uses Material3 adaptive Ta5d6ff`ListDetailSceneStrategy` to automatically provide a split-pane layout on large screens.
Tc9d1d9## Dependency Graph
Tc9d1d9### Key Dependencies
Ta5d6ff```
feature:docs
βββ core:common, core:navigation, core:resources, core:ui, core:di
βββ coil (image loading in Markdown)
βββ markdown-renderer-m3 (Compose Markdown rendering)
βββ compose.material3.adaptive, compose.material3.adaptive.navigation3
βββ kotlinx.collections.immutable
```
<!--region graph-->
Ta5d6ff```Ta5d6ffmermaid
Ta5d6ffgraph TB
:feature:docs[docs]:::kmp-feature
:feature:docs -.-> :core:common
:feature:docs -.-> :core:navigation
:feature:docs -.-> :core:resources
:feature:docs -.-> :core:ui
:feature:docs -.-> :core:di
:feature:docs -.-> :core:testing
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef compose-desktop-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
classDef android-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef android-library fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-library-compose fill:#9BF6FF,stroke:#000,stroke-width:2px,color:#000;
classDef android-test fill:#A0C4FF,stroke:#000,stroke-width:2px,color:#000;
classDef jvm-library fill:#BDB2FF,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-feature fill:#FFD6A5,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library-compose fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef kmp-library fill:#FFC1CC,stroke:#000,stroke-width:2px,color:#000;
classDef unknown fill:#FFADAD,stroke:#000,stroke-width:2px,color:#000;
Ta5d6ff```
<!--endregion-->
Served by rngit 1.5.0 - Generated in 0.06s